#include <bits/stdc++.h>
#define int long long 
using namespace std;

const int maxn = 1e5 + 10;
const int inf=2e18;
int n, m;
int dist[maxn]; // 每个节点距离 mst 集合的最短距离
bool vis[maxn];
		
struct Edge{
	int y,w;
	
	bool operator < (const Edge& e) const{
		return w==e.w? y<e.y: w>e.w;
	}
};
vector<Edge> adj[maxn];
		
int prim(){
	int ans=0;
	priority_queue<Edge> pq;
	pq.push({1, dist[1]=0});
	while(pq.size()){
		int x = pq.top().y; pq.pop();
		if(vis[x]){
			continue;
		}
		vis[x]=true;
		ans=max(ans, dist[x]); // 注意这行代码的位置不能随意动
		// 因为 vis[x] 设置为 true 才表示真正选择了这个节点连接的某条边, 此时才能更新最大值, 而不是在 下面的循环中直接就更新
		for(auto const& [y, w]: adj[x]){
			if(vis[y]){
				continue;
			}
			if(w<dist[y]){
				dist[y]=w;
				pq.push({y, dist[y]});
			}
		}
	}
	return ans;
}
		
void solve(){
	cin>>n>>m;
	
	for(int i=1;i<=n;i++){ // 多组样例, 需要初始化
		dist[i]=inf;
		adj[i].clear();
		vis[i]=false;
	}
	for(int i=1;i<=m;i++){
		int x,y,c;
		cin>>x>>y>>c;
		adj[x].push_back({y, c});
		adj[y].push_back({x, c});
	}
	
		
	
	cout<<prim()<<'\n';
}

signed main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}
